using System.Net;
using System.Net.Sockets;
using Serilog;

namespace MoonFramework.Net
{
    /// <summary>
    /// 负责监听TCP网络端口，异步接收Socket连接
    /// --Connected
    /// --DataReceived
    /// --Disconnected
    /// IsRunning
    /// Stop()  关闭服务器
    /// Start() 开启服务器
    /// </summary>
    public class TcpServer
    {
        private IPEndPoint endPoint;
        private Socket serverSocket;
        private SocketAsyncEventArgs args;
        private int backlog = 100; //可以排队接收的连入连接数
		
        public bool IsRunning => serverSocket != null;

        public event EventHandler<Socket> SocketConnected;
        public Action<BaseConnection> OnConnected;
        public Action<BaseConnection, byte[]> OnDataReceived;
        public Action<BaseConnection> OnDisConnected;

        public TcpServer(string host, int port)
        {
            endPoint = new IPEndPoint(IPAddress.Parse(host), port);
        }

        public TcpServer(string host, int port, int backlog) : this(host, port)
        {
            this.backlog = backlog;
        }

        public void Start()
        {
            try
            {
                if (!IsRunning)
                {
                    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    serverSocket.Bind(endPoint);
                    serverSocket.Listen(backlog);
                    Log.Information("开始监听端口：" + endPoint.Port);

                    args = new SocketAsyncEventArgs();
                    args.Completed += OnAccept;
                    serverSocket.AcceptAsync(args);
                }
            }
            catch (Exception ex)
            {
                Log.Error($"启动监听时发生异常：{ ex.Message }");
            }
        }

        private void OnAccept(object? sender, SocketAsyncEventArgs e)
        {
            try
            {
                Socket client = e.AcceptSocket;
                e.AcceptSocket = null;
                serverSocket.AcceptAsync(e);
                if (e.SocketError == SocketError.Success)
                {
                    if (client != null)
                        OnSocketConnected(client);
                }

            }
            catch (Exception ex)
            {
                Log.Error($"OnAccept Error：{ex.Message} ");
            }
        }

        private void OnSocketConnected(Socket client)
        {
            //TODO:后续处理连接后的回调
            SocketConnected?.Invoke(this, client);
        }

        public void Stop()
        {
            try
            {
                if (serverSocket != null)
                {
                    serverSocket.Close();
                    serverSocket = null;
                    args?.Dispose();
                    Log.Information("监听器已停止。");
                }
            }
            catch (Exception ex)
            {
                Log.Error("停止监听时发生异常：" + ex.Message);
            }
        }
    }
}